<form nz-form [formGroup]="validateForm" nzLayout="vertical" class="search-form">
  <div nz-row [nzGutter]="24">
    <div nz-col [nzSpan]="6">
      <nz-form-item>
        <nz-form-label nzFor="id">Id</nz-form-label>
        <nz-form-control>
          <input type="text" formControlName="id" nz-input/>
        </nz-form-control>
      </nz-form-item>
    </div>
    <div nz-col [nzSpan]="6">
      <nz-form-item>
        <nz-form-label nzFor="eventId">EventId</nz-form-label>
        <nz-form-control>
          <input type="text" formControlName="eventId" nz-input/>
        </nz-form-control>
      </nz-form-item>
    </div>
    <div nz-col [nzSpan]="6">
      <nz-form-item>
        <nz-form-label nzFor="aggregateId">AggregateId</nz-form-label>
        <nz-form-control>
          <input type="text" formControlName="aggregateId" nz-input/>
        </nz-form-control>
      </nz-form-item>
    </div>
    <div nz-col [nzSpan]="6">
      <nz-form-item>
        <nz-form-label nzFor="aggregateContext">AggregateContext</nz-form-label>
        <nz-form-control>
          <input type="text" formControlName="aggregateContext" nz-input/>
        </nz-form-control>
      </nz-form-item>
    </div>
    <div nz-col [nzSpan]="6">
      <nz-form-item>
        <nz-form-label nzFor="aggregateName">AggregateName</nz-form-label>
        <nz-form-control>
          <input type="text" formControlName="aggregateName" nz-input/>
        </nz-form-control>
      </nz-form-item>
    </div>
    <div nz-col [nzSpan]="6">
      <nz-form-item>
        <nz-form-label nzFor="processorContext">ProcessorContext</nz-form-label>
        <nz-form-control>
          <input type="text" formControlName="processorContext" nz-input/>
        </nz-form-control>
      </nz-form-item>
    </div>
    <div nz-col [nzSpan]="6">
      <nz-form-item>
        <nz-form-label nzFor="processorName">ProcessorName</nz-form-label>
        <nz-form-control>
          <input type="text" formControlName="processorName" nz-input/>
        </nz-form-control>
      </nz-form-item>
    </div>
    <div nz-col [nzSpan]="6">
      <div style="margin-top: 24px">
        <button nz-button nzType="primary" (click)="load()" [nzLoading]="loading">
          <span nz-icon nzType="search"></span>
          Search
        </button>
        <button style="margin-left: 8px" nz-button nzType="default" (click)="reset()" [nzLoading]="loading"
                [disabled]="!this.validateForm.dirty">
          <span nz-icon nzType="rest"></span>
          Reset
        </button>
      </div>
    </div>
  </div>
</form>

<nz-table nzBordered nzSize="middle" [nzScroll]="{ x: '1200px' }"
          nzShowSizeChanger [nzFrontPagination]="false" [nzHideOnSinglePage]="true"
          [nzPageIndex]="pagedQuery.pagination.index" [nzPageSize]="pagedQuery.pagination.size"
          [nzData]="pagedList.list" [nzTotal]="pagedList.total" [nzShowTotal]="totalTemplate"
          (nzQueryParams)="onQueryParamsChange($event)" [nzLoading]="loading"
>
  <thead>
  <tr>
    <th rowspan="2" width="36px"></th>
    <th rowspan="2" nzLeft nzColumnKey="_id" [nzSortFn]="true" [nzSortPriority]="1">Id</th>
    <th colspan="4">Processor</th>
    <th colspan="5">EventId</th>
    <th colspan="3">RetryState</th>
    <th rowspan="2" width="60px">Status</th>
    <th rowspan="2" width="130px">Recoverable</th>
    <th rowspan="2" width="120px" nzRight>Operation</th>
  </tr>
  <tr>
    <th nzColumnKey="state.processor.contextName" [nzSortFn]="true" [nzSortPriority]="9">Context</th>
    <th nzColumnKey="state.processor.processorName" [nzSortFn]="true" [nzSortPriority]="8">Name</th>
    <th>FunctionKind</th>
    <th nzColumnKey="state.executeAt" [nzSortFn]="true" [nzSortPriority]="4">ExecuteAt</th>
    <th nzColumnKey="state.eventId.aggregateId.contextName">Context</th>
    <th nzColumnKey="state.eventId.aggregateId.aggregateName">Aggregate</th>
    <th nzColumnKey="state.eventId.aggregateId.aggregateId">AggregateId</th>
    <th nzColumnKey="state.eventId.id" [nzSortFn]="true" [nzSortPriority]="2">Id</th>
    <th nzColumnKey="state.eventId.version" [nzSortFn]="true" [nzSortPriority]="3">Version</th>
    <th nzColumnKey="state.retryState.retries" [nzSortFn]="true" [nzSortPriority]="5">
      Retries
    </th>
    <th nzColumnKey="state.retryState.retryAt" [nzSortFn]="true" [nzSortPriority]="6">RetryAt</th>
    <th nzColumnKey="state.retryState.nextRetryAt" [nzSortFn]="true" [nzSortPriority]="7">NextRetryAt</th>
  </tr>
  <tbody>
  <ng-container *ngFor="let item of pagedList.list">
    <tr>
      <td [nzExpand]="expandSet.has(item.id)" (nzExpandChange)="onExpandChange(item.id, $event)">

      </td>
      <td nzLeft>
        <p nz-typography nzEllipsis nzCopyable [(nzContent)]="item.id"></p>
      </td>
      <td>{{ item.processor.contextName }}</td>
      <td>{{ item.processor.processorName }}</td>
      <td>
        <nz-select [(ngModel)]="item.functionKind" [nzBorderless]="true" nzSize="small"
                   (ngModelChange)="changeFunctionKind(item.id,$event)">
          <nz-option nzValue="EVENT" nzLabel="Event"></nz-option>
          <nz-option nzValue="STATE_EVENT" nzLabel="StateEvent"></nz-option>
        </nz-select>
      </td>
      <td>{{ item.executeAt|date:'yyyy-MM-dd HH:mm:ss' }}</td>
      <td>{{ item.eventId.aggregateId.contextName }}</td>
      <td>{{ item.eventId.aggregateId.aggregateName }}</td>
      <td>
        <p nz-typography nzEllipsis nzCopyable [(nzContent)]="item.eventId.aggregateId.aggregateId"></p>
      </td>
      <td>
        <p nz-typography nzEllipsis nzCopyable [(nzContent)]="item.eventId.id"></p>
      </td>
      <td> {{ item.eventId.version }}</td>
      <td>
        {{ item.retryState.retries }}({{ item.retrySpec.maxRetries }})
        <ng-template [ngIf]="category!=FindCategory.SUCCESS">
          <button nz-button nzType="dashed" nzDanger nzShape="circle" nzSize="small"
                  (click)="editRetrySpec(item.id,item.retrySpec)">
            <span nz-icon nzType="edit"></span>
          </button>
        </ng-template>
      </td>
      <td>{{ item.retryState.retryAt|date:'yyyy-MM-dd HH:mm:ss' }}</td>
      <td>
        @switch (category) {
          @case (FindCategory.TO_RETRY) {
            <nz-countdown [nzValue]="item.retryState.nextRetryAt"
                          [nzValueStyle]="{ color: '#3F8600','font-size':'medium' }"></nz-countdown>
          }
          @default {
            -
          }
        }
      </td>
      <td style="text-align: center;font-size: large">
        @switch (item.status) {
          @case (ExecutionFailedStatus.FAILED) {
            <span nz-icon nzType="close" style="color: #b62a3c" nz-tooltip nzTooltipPlacement="left"
                  nzTooltipTitle="{{item.status}}"></span>
          }
          @case (ExecutionFailedStatus.PREPARED) {
            <span nz-icon nzType="sync" [nzSpin]="true" style="color: #00a4ff" nz-tooltip nzTooltipPlacement="left"
                  nzTooltipTitle="{{item.status}}"></span>
          }
          @case (ExecutionFailedStatus.SUCCEEDED) {
            <span nz-icon nzType="check" style="color: #52c41a" nz-tooltip nzTooltipPlacement="left"
                  nzTooltipTitle="{{item.status}}"></span>
          }
        }
      </td>
      <td>
        <nz-select [(ngModel)]="item.recoverable" [nzBorderless]="true" nzSize="small"
                   (ngModelChange)="markRecoverable(item.id,$event)">
          <nz-option nzValue="RECOVERABLE" nzLabel="Recoverable"></nz-option>
          <nz-option nzValue="UNRECOVERABLE" nzLabel="Unrecoverable"></nz-option>
          <nz-option nzValue="UNKNOWN" nzLabel="Unknown"></nz-option>
        </nz-select>
      </td>
      <td nzRight>
        <nz-button-group>
          <button nz-button (click)="openErrorInfo(item)" nzSize="small"
                  nz-popover [nzPopoverOverlayStyle]="{width: '50vw'}"
                  [nzPopoverTitle]="item.error.errorCode" [nzPopoverContent]="item.error.errorMsg">
            Error
          </button>
          <ng-template [ngIf]="category==FindCategory.TO_RETRY">
            <button nz-popconfirm
                    nzPopconfirmTitle="Are you sure retry this Failed?"
                    nzPopconfirmPlacement="top"
                    nz-button
                    (nzOnConfirm)="prepare(item.id)"
                    nzSize="small"
            >
              Retry
            </button>
          </ng-template>
          <ng-template [ngIf]="category==FindCategory.NON_RETRYABLE||category==FindCategory.UNRECOVERABLE">
            <button nz-popconfirm
                    [nzPopconfirmTitle]="'Are you sure force retry this Failed?'"
                    nzPopconfirmPlacement="top"
                    nz-button
                    (nzOnConfirm)="forcePrepare(item.id)"
                    nzSize="small"
                    nzDanger
            >
              F-Retry
            </button>
          </ng-template>
        </nz-button-group>
      </td>
    </tr>
    <ng-template [ngIf]="expandSet.has(item.id)">
      <tr [nzExpand]="expandSet.has(item.id)">
        <app-failed-history [id]="item.id"></app-failed-history>
      </tr>
    </ng-template>
  </ng-container>
  </tbody>
</nz-table>
<ng-template #totalTemplate let-total>Total {{ total }} items</ng-template>
<nz-drawer
  [nzClosable]="false"
  [nzVisible]="errorInfoVisible"
  nzPlacement="right"
  nzTitle="Error Info"
  (nzOnClose)="closeErrorInfo()"
  [nzExtra]="drawerOperateTpl"
  nzWidth="80vw"
>
  <ng-container *nzDrawerContent>
    <ng-template [ngIf]="errorInfoVisible">
      <app-error [state]="current!"></app-error>
    </ng-template>
  </ng-container>
</nz-drawer>

<ng-template #drawerOperateTpl>
  <button nz-popconfirm
          [nzPopconfirmTitle]="'Are you sure force retry this Failed?'"
          nzPopconfirmPlacement="top"
          nz-button
          (nzOnConfirm)="forcePrepare(current?.id!!)"
          nzDanger
  > F-Retry
  </button>
</ng-template>
